package com.wxapp.custom.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wxapp.common.constant.base.IBaseService;
import com.wxapp.common.constant.pojo.vm.ResultVm;
import com.wxapp.common.constant.pojo.vo.UserVo;
import com.wxapp.common.util.check.CheckUtil;
import com.wxapp.common.util.condition.ConditionUtil;
import com.wxapp.common.util.copy.CopyUtil;
import com.wxapp.custom.api.feign.CouponUserFeign;
import com.wxapp.custom.api.pojo.entity.CustomAccountDO;
import com.wxapp.custom.api.pojo.vm.customAccount.PCustomAccountDetailVm;
import com.wxapp.custom.api.pojo.vm.customAccount.PCustomAccountPageVm;
import com.wxapp.custom.api.pojo.vo.customAccount.QCustomAccountAddVo;
import com.wxapp.custom.api.pojo.vo.customAccount.QCustomAccountPageVo;
import com.wxapp.custom.api.pojo.vo.customAccount.QCustomAccountVo;
import com.wxapp.custom.api.pojo.vo.customAccount.QCustomAccountUpdateVo;
import com.wxapp.custom.service.mapper.AccountMapper;
import com.wxapp.custom.service.service.AccountService;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * @author lgl
 * @Description 用户账户
 * @Datetime 2022/7/4 15:55
 * @Modified By
 */
@Service
@RequiredArgsConstructor
public class AccountServiceImpl extends IBaseService implements AccountService {
    private final AccountMapper accountMapper;
    @Qualifier("com.wxapp.custom.api.feign.CouponUserFeign")
    private final CouponUserFeign couponUserFeign;

    @Override
    public ResultVm<PCustomAccountDetailVm> getAccount(UserVo userVo) {
        LambdaQueryWrapper<CustomAccountDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CustomAccountDO::getCustomId, userVo.getCustomId()).eq(CustomAccountDO::getStatus, true);
        var couponCount = couponUserFeign.getCouponCount(userVo.getId());
        var wxappCustomAccountDO = accountMapper.selectFirst(wrapper);
        PCustomAccountDetailVm pWxappVo;
        if (CheckUtil.isNullObject(wxappCustomAccountDO)) {
            pWxappVo = new PCustomAccountDetailVm();
            pWxappVo.setBalanceIntegral(BigDecimal.ONE);
            pWxappVo.setBalanceRmb(BigDecimal.ONE);
        } else {
            pWxappVo = new PCustomAccountDetailVm();
            pWxappVo.setBalanceIntegral(wxappCustomAccountDO.getBalanceIntegral());
            pWxappVo.setBalanceRmb(wxappCustomAccountDO.getBalanceRmb());
        }
        pWxappVo.setCouponCount(couponCount.getData());
        return success(pWxappVo);
    }

    @Override
    public ResultVm<PCustomAccountDetailVm> getUserAccount(String id) {
        LambdaQueryWrapper<CustomAccountDO> lambda = new LambdaQueryWrapper<>();
        lambda.eq(CustomAccountDO::getId, id);
        lambda.eq(CustomAccountDO::getStatus, false);
        var selectOne = accountMapper.selectFirst(lambda);
        var pGetUserAccountVo = CopyUtil.copyObjectNew(selectOne, PCustomAccountDetailVm::new, null);
        var couponCount = couponUserFeign.getCouponCount(id);
        pGetUserAccountVo.setCouponCount(couponCount.getData());
        return success(pGetUserAccountVo);
    }

    @Override
    public ResultVm<String> update(QCustomAccountUpdateVo qCustomAccountUpdateVo, UserVo userVo) {
        LambdaQueryWrapper<CustomAccountDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CustomAccountDO::getCustomId, qCustomAccountUpdateVo.getCustomId());
        wrapper.eq(CustomAccountDO::getStatus, false);
        var selectOne = accountMapper.selectFirst(wrapper);
        if (CheckUtil.isNullObject(selectOne)) {
            if (CheckUtil.isNullObject(qCustomAccountUpdateVo.getBalanceIntegral())) {
                selectOne.setBalanceIntegral(selectOne.getBalanceIntegral().add(qCustomAccountUpdateVo.getBalanceIntegral()));
            }
            if (CheckUtil.isNullObject(qCustomAccountUpdateVo.getBalanceRmb())) {
                selectOne.setBalanceRmb(selectOne.getBalanceRmb().add(qCustomAccountUpdateVo.getBalanceRmb()));
            }
            selectOne.setUpdateBy(userVo.getId());
            accountMapper.updateById(selectOne);
        } else {
            var wxappCustomAccountDO = CopyUtil.copyObjectNew(qCustomAccountUpdateVo, CustomAccountDO::new, null);
            wxappCustomAccountDO.setCreateBy(userVo.getId());
            accountMapper.insert(wxappCustomAccountDO);
        }
        return success();
    }

    @Override
    public ResultVm<Page<PCustomAccountPageVm>> page(QCustomAccountPageVo qCustomAccountPageVo) {
        var page = ConditionUtil.getPage(qCustomAccountPageVo, PCustomAccountPageVm.class);
        Page<PCustomAccountPageVm> result = accountMapper.page(page, qCustomAccountPageVo);
        return success(result);
    }

    @Override
    public ResultVm<String> save(UserVo userVo, QCustomAccountAddVo qCustomAccountAddVo) {
        LambdaQueryWrapper<CustomAccountDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CustomAccountDO::getCustomId, qCustomAccountAddVo.getCustomId()).eq(CustomAccountDO::getStatus, true);
        var count = accountMapper.selectCount(wrapper);
        if (count > 0) {
            return error("用户已经开户！！");
        }
        var CustomAccountDO = CopyUtil.copyObjectNew(qCustomAccountAddVo, CustomAccountDO::new, (s, r) -> {
            r.setCreateBy(userVo.getId());
            return null;
        });
        accountMapper.insert(CustomAccountDO);
        return success("开户成功");
    }

    @Override
    @GlobalTransactional(rollbackFor = {Exception.class, RuntimeException.class})
    public  ResultVm<String> pay(QCustomAccountVo vo){
        LambdaQueryWrapper<CustomAccountDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CustomAccountDO::getCreateBy, vo.getUserId())
                .eq(CustomAccountDO::getStatus, true);
        var first = accountMapper.selectFirst(wrapper);
        if (CheckUtil.isNullObject(first)) {
            return error("没有查到用户账户信息");
        }
        if (CheckUtil.isNullBigDecimal(vo.getBalanceIntegral()) && CheckUtil.isNullBigDecimal(vo.getBalanceRmb())){
            return error("账户没有余额");
        }
        if (CheckUtil.isNotNullBigDecimal(vo.getBalanceIntegral())) {
            if (first.getBalanceIntegral().compareTo(vo.getBalanceIntegral())<0){
                return error("账户余额不足");
            }
            first.setBalanceIntegral(first.getBalanceIntegral().subtract(vo.getBalanceIntegral()));
        }
        if (CheckUtil.isNotNullBigDecimal(vo.getBalanceRmb())) {
            if (first.getBalanceRmb().compareTo(vo.getBalanceRmb())<0){
                return error("账户余额不足");
            }
            first.setBalanceRmb(first.getBalanceRmb().subtract(vo.getBalanceRmb()));
        }
        accountMapper.updateById(first);
        return success();
    }
}
